package com.six.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.six.domain.dto.LoginDto;
import com.six.domain.dto.TokenVo;
import com.six.domain.entity.User;
import com.six.enums.RoleEnum;
import com.six.mapper.UserMapper;
import com.six.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class AuthService {
    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;
    private final RedisTemplate<String, String> redisTemplate;
    private final ObjectMapper objectMapper;

    public TokenVo login(LoginDto dto) {
        User user = userMapper.selectByUsername(dto.getUsername());
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }
        if (!user.getIsActive()) {
            throw new RuntimeException("账号已被禁用");
        }
        if (!passwordEncoder.matches(dto.getPassword(), user.getPasswordHash())) {
            throw new RuntimeException("用户名或密码错误");
        }
        log.info(">>> 登录用户 {} 的 storeId = {}", user.getUsername(), user.getStoreId());

        String access = jwtUtil.generateToken(
                user.getId(),
                user.getUsername(),
                user.getRoleId(),
                user.getStoreId(),
                user.getStoreName());
        String refresh = jwtUtil.generateToken(
                user.getId(),
                user.getUsername(),
                user.getRoleId(),
                user.getStoreId(),
                user.getStoreName());// ⬅️ 新增
        TokenVo vo = new TokenVo(access, refresh);

        try {
            String json = objectMapper.writeValueAsString(vo);
            String key = "user:token:" + user.getUsername();
            redisTemplate.opsForValue().set(key, json, jwtUtil.getExpire(), TimeUnit.SECONDS);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Token 序列化失败", e);
        }
        return vo;
    }

    @Transactional
    public void createWaiter(Long storeId, String name, String phone, String pwd) {
        User user = new User();
        user.setUsername(phone);
        user.setPasswordHash(passwordEncoder.encode(pwd));
        user.setPhone(phone);
        user.setEmail(null);
        user.setRoleId(RoleEnum.WAITER.getId());      // WAITER
        user.setIsActive(true);
        user.setStoreId(storeId);
        userMapper.insertUser(user);
    }

    public void updatePassword(String username, String oldRaw, String newRaw){
        User u = userMapper.selectByUsername(username);
        if (!passwordEncoder.matches(oldRaw, u.getPasswordHash()))
            throw new RuntimeException("原密码错误");
        userMapper.updatePassword(u.getId(), passwordEncoder.encode(newRaw));
    }

    public void toggleWaiter(Long waiterId, boolean active) {
        userMapper.updateStatus(waiterId, active);
    }
}